package com.xyzwps.paimon.furina.infra

import com.fasterxml.jackson.databind.ObjectMapper
import com.xyzwps.paimon.furina.common.JSON
import org.jetbrains.exposed.sql.Database
import org.jetbrains.exposed.sql.transactions.TransactionManager
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.crypto.argon2.Argon2PasswordEncoder
import org.springframework.security.crypto.password.DelegatingPasswordEncoder
import org.springframework.security.crypto.password.PasswordEncoder
import javax.sql.DataSource

private const val ARGON2_SALT_LEN = 16
private const val ARGON2_HASH_LEN = 32
private const val ARGON2_PARALLELISM = 1
private const val ARGON2_MEMORY = 32
private const val ARGON2_ITERATION = 2

private const val PE_ARGON2 = "argon2"

@Configuration
class Beans {

    @Bean
    fun db(dataSource: DataSource): Database {
        val db = Database.connect(dataSource)
        TransactionManager.defaultDatabase = db
        return db
    }

    @Bean
    fun objectMapper(): ObjectMapper = JSON.OM

    @Bean
    fun passwordEncoder(): PasswordEncoder {
        val argon2Encoder = Argon2PasswordEncoder(
            ARGON2_SALT_LEN,
            ARGON2_HASH_LEN,
            ARGON2_PARALLELISM,
            ARGON2_MEMORY,
            ARGON2_ITERATION
        )
        return DelegatingPasswordEncoder(PE_ARGON2, mapOf(PE_ARGON2 to argon2Encoder))
    }

}